﻿using BeerScanatronClient;
using BeerScanatronClient.Entities;
using BeerScanatronTestUI.ScannerServiceReference;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BeerScanatronTestUI
{
    public partial class Form1 : Form
    {
        private BasicHttpBinding _binding;
        private EndpointAddress _address;
        private static Random _random = new Random((int)DateTime.Now.Ticks);

        public Form1()
        {
            InitializeComponent();

            Uri baseAddress = new UriBuilder("http", "localhost", Properties.Settings.Default.ServerPort, "BeerScanatron").Uri;
            lblUrl.Text = baseAddress.AbsoluteUri;
            _binding = new BasicHttpBinding();
            _address = new EndpointAddress(baseAddress);
        }

        private void btnAddBeer_Click(object sender, EventArgs e)
        {
            try
            {
                using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
                {
                    client.AddBeer(new Beer() { Brand = RandomString(8), Name = RandomString(8), Type = RandomString(20), BarCode = RandomString(8) });
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Failed to add beer!");
            }
        }

        /// <summary>
        /// Get Beers
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
                {
                    string beerList = string.Empty;
                    client.GetBeers().ToList().ForEach(b => beerList += beerList == string.Empty ? b.Name : $"; {b.Name}");
                    MessageBox.Show(beerList, "Beer list");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Failed to add beer!");
            }
        }

        /// <summary>
        /// Delete beers
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
                {
                    var beers = client.GetBeers();
                    client.DeleteBeers(beers);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Failed to add beer!");
            }
        }

        /// <summary>
        /// Update Beers
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
            {
                string beerList = string.Empty;
                var beers = client.GetBeers();
                foreach (Beer beer in beers)
                {
                    beer.Name = RandomString(8);
                    beer.Type = RandomString(10);
                }

                client.UpdateBeers(beers);
            }
        }

        private string RandomString(int size)
        {
            StringBuilder builder = new StringBuilder();
            char ch;
            for (int i = 0; i < size; i++)
            {
                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * _random.NextDouble() + 65)));
                builder.Append(ch);
            }

            return builder.ToString();
        }

        private void btnAddDrinker_Click(object sender, EventArgs e)
        {
            try
            {
                using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
                {
                    client.AddDrinker(new Drinker() { FirstName = RandomString(8), LastName = RandomString(8), BarCode = RandomString(8), CanServe = true });
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Failed to add drinker!");
            }
        }

        private void btnDeleteDrinker_Click(object sender, EventArgs e)
        {
            try
            {
                using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
                {
                    var drinkers = client.GetDrinkers();
                    client.DeleteDrinkers(drinkers);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Failed to delete drinkers!");
            }
        }

        private void btnUpdateDrinker_Click(object sender, EventArgs e)
        {
            using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
            {
                var drinkers = client.GetDrinkers();
                foreach (Drinker drinker in drinkers)
                {
                    drinker.LastName = RandomString(8);
                    drinker.FirstName = RandomString(10);
                }

                client.UpdateDrinkers(drinkers);
            }
        }

        private void btnGetDrinker_Click(object sender, EventArgs e)
        {
            try
            {
                using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
                {
                    string drinkerList = string.Empty;
                    client.GetDrinkers().ToList().ForEach(b => drinkerList += drinkerList == string.Empty ? b.FirstName : $"; {b.FirstName}");
                    MessageBox.Show(drinkerList, "Drinker list");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Failed to get drinkers!");
            }
        }

        private void btnAddDrinkerPicture_Click(object sender, EventArgs e)
        {
            try
            {
                using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
                {
                    var drinkers = client.GetDrinkers();
                    List<DrinkerPicture> pictures = new List<DrinkerPicture>();

                    foreach (Drinker drinker in drinkers)
                    {
                        byte[] picture = new byte[64];
                        Random random = new Random();
                        random.NextBytes(picture);

                        client.AddUpdatePictures(new DrinkerPicture() { DrinkerID = drinker.Id, Picture = picture });
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Failed to add drinker picture!");
            }
        }

        private void btnGetDrinkerPicture_Click(object sender, EventArgs e)
        {
            try
            {
                using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
                {
                    var drinker = client.GetDrinkers().First();

                    var pictures = client.GetPicture(drinker);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Failed to get drinkers!");
            }
        }

        private void btnAddDrinkDisbersment_Click(object sender, EventArgs e)
        {
            try
            {
                using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
                {
                    var drinkers = client.GetDrinkers().ToArray();
                    if (drinkers == null || !drinkers.Any())
                    {
                        MessageBox.Show("Sorry, there's no drinkers for which for how come to drink!");
                    }

                    var beers = client.GetBeers().ToArray();
                    if (beers == null || !beers.Any())
                    {
                        MessageBox.Show("Sorry, there ain't no beer at'all!");
                    }

                    client.AddDispensor(new DispenserInfo(drinkers[_random.Next(drinkers.Count())], beers[_random.Next(beers.Count())]));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Failed to add dispensermentation!");
            }
        }

        private void btnGetDrinkDisbursements_Click(object sender, EventArgs e)
        {
            try
            {
                using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
                {
                    List<string> drinkings = new List<string>();
                    client.GetDispensors().ToList().ForEach(delegate (DispenserInfo d)
                       {
                           Beer beer = client.GetBeers().Single(b => b.Id == d.BeerID);
                           Drinker drinker = client.GetDrinkers().Single(dr => dr.Id == d.DrinkerID);
                           drinkings.Add($"{drinker.ToString()} drank a {beer.ToString()} at {d.ServeDate}!");
                       });

                    MessageBox.Show(string.Join(Environment.NewLine, drinkings), "Disbersementtationators");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Failed to get drinkers!");
            }
        }

        /// <summary>
        /// Add a DispensorInfo item to the database.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDispenseInfoAddItem_Click(object sender, EventArgs e)
        {
            using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
            {
                Drinker drinker = client.GetDrinkers().First();
                Beer beer = client.GetBeers().First();

                DispenserInfo dInfo = new DispenserInfo(drinker, beer);
                client.AddDispensor(dInfo);
            }
        }

        /// <summary>
        /// Get all DispensorInfo items from the database.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDispenseInfoGetAll_Click(object sender, EventArgs e)
        {
            using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
            {
                rtbDispense.Clear();
                foreach (var d in client.GetDispensors())
                {
                    rtbDispense.AppendText(d.ServeDate.ToString() + ": " + d.DrinkerID + ", " + d.BeerID + "\n");
                }
            }
        }

        private void btnDispenseInfoGetDate_Click(object sender, EventArgs e)
        {
            using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
            {
                rtbDispense.Clear();
                foreach (var d in client.GetDispensorsByDate(dateTimePicker1.Value))
                {
                    rtbDispense.AppendText(d.ServeDate.ToString() + ": " + d.DrinkerID + ", " + d.BeerID + "\n");
                }
            }
        }

        private void btnDeleteDate_Click(object sender, EventArgs e)
        {
            using (ScaningServiceClient client = new ScaningServiceClient(_binding, _address))
            {
                client.DeleteDispensorsByDate(dateTimePicker1.Value);
            }
        }
    }
}